const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger') // 美化console.log打印格式，更清晰好看
const session = require('koa-generic-session')
const RedisStore = require('koa-redis')
const Redis = require('redis')

const path = require('path')
const fs = require('fs')
const morganLogger = require('morgan')
const koaConnect = require('koa-connect')

const { My_Redis_CONFIG } = require('./conf/db')

const index = require('./routes/index')
const users = require('./routes/users')
const blog = require('./routes/blog')
const user = require('./routes/user')

// error handler
onerror(app)

// middlewares
app.use(
  bodyparser({
    enableTypes: ['json', 'form', 'text'],
  })
)
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))

app.use(
  views(__dirname + '/views', {
    extension: 'pug',
  })
)

// logger
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// 创建 Redis 客户端
const redisClient = Redis.createClient({
  host: My_Redis_CONFIG.host, // Redis 服务器地址
  port: My_Redis_CONFIG.port, // Redis 端口
})
redisClient.on('connect', () => {
  console.log('Redis连接成功')
})

// 日志记录📝
const ENV = process.env.NODE_ENV

if (ENV === 'production') {
  // 开发环境 / 测试环境
  app.use(koaConnect(morganLogger('dev')))
} else {
  console.log(ENV, '---- 记录日志 ---')
  // 线上环境
  const logFileName = path.join(__dirname, 'logs', 'access.log')
  const writeStream = fs.createWriteStream(logFileName, {
    flags: 'a',
  })
  app.use(
    koaConnect(
      morganLogger('combined', {
        stream: writeStream,
      })
    )
  )
}

// 配置 session 中间件
app.keys = ['chienli8888'] // 设置一个安全密钥
app.use(
  session({
    cookie: {
      path: '/',
      httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000,
    },
    store: new RedisStore({
      client: redisClient,
    }),
  })
)

// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
app.use(blog.routes(), blog.allowedMethods())
app.use(user.routes(), user.allowedMethods())

// error-handling
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
})

module.exports = app
